﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.IO;
using NUnit.Framework;
class Program
{
    static void Main()
    {
        OrderService orderService = new OrderService();
        try
        {
            // 添加订单
            Order order1 = new Order(1, "客户A");
            order1.AddOrderDetail(new OrderDetails(1, "商品A", 10, 5.0));
            order1.AddOrderDetail(new OrderDetails(2, "商品B", 2, 20.0));
            orderService.AddOrder(order1);

            Order order2 = new Order(2, "客户B");
            order2.AddOrderDetail(new OrderDetails(3, "商品C", 1, 100.0));
            orderService.AddOrder(order2);

            // 查询订单
            String test = order1.Customer;
            var queryResult = orderService.ByName(test);
            Console.WriteLine("查询结果:");
            foreach (var order in queryResult)
                Console.WriteLine(order);
            var data1 = orderService.ByOrderid(1);
            Console.WriteLine("查询结果:");
            foreach (var order in data1)
                Console.WriteLine(order);
            var data2 = orderService.ByOrdername("商品C");
            Console.WriteLine("查询结果:");
            foreach (var order in data2)
                Console.WriteLine(order);
            var data3 = orderService.ByMoney(90.0);
            Console.WriteLine("查询结果:");
            foreach (var order in data3)
                Console.WriteLine(order);
            // 删除订单
            orderService.RemoveOrder(2);
        }
        catch (Exception e)
        {
            Console.WriteLine("错误: " + e.Message);
        }
    }
}

class Order
{
    public int OrderId { get; }
    public string Customer { get; }
    public List<OrderDetails> OrderDetailsList { get; }

    public double TotalAmount => OrderDetailsList.Sum(d => d.TotalPrice);

    public Order(int orderId, string customer)
    {
        OrderId = orderId;
        Customer = customer;
        OrderDetailsList = new List<OrderDetails>();
    }

    public void AddOrderDetail(OrderDetails detail)
    {
        if (OrderDetailsList.Contains(detail))
            throw new Exception("订单明细重复!");
        OrderDetailsList.Add(detail);
    }

    public override bool Equals(object obj)
    {
        return obj is Order order && OrderId == order.OrderId;
    }

    public override int GetHashCode()
    {
        return OrderId.GetHashCode();
    }

    public override string ToString()
    {
        return $"订单号: {OrderId}, 客户: {Customer}, 总金额: {TotalAmount:C}, 明细: [{string.Join(", ", OrderDetailsList)}]";
    }
}

class OrderDetails
{
    public int DetailId { get; }
    public string ProductName { get; }
    public int Quantity { get; }
    public double UnitPrice { get; }
    public double TotalPrice { get; }

    public OrderDetails(int detailId, string productName, int quantity, double unitPrice)
    {
        DetailId = detailId;
        ProductName = productName;
        Quantity = quantity;
        UnitPrice = unitPrice;
        TotalPrice = Quantity * UnitPrice;
    }

    public override bool Equals(object obj)
    {
        return obj is OrderDetails detail && DetailId == detail.DetailId;
    }

    public override int GetHashCode()
    {
        return DetailId.GetHashCode();
    }

    public override string ToString()
    {
        return $"{ProductName} x {Quantity} @ {UnitPrice:C} = {TotalPrice:C}";
    }
}

class OrderService
{
    private List<Order> orders = new List<Order>();

    public void AddOrder(Order order)
    {
        if (orders.Contains(order))
            throw new Exception("订单已存在!");
        orders.Add(order);
    }

    public void RemoveOrder(int orderId)
    {
        Order order = orders.FirstOrDefault(o => o.OrderId == orderId);
        if (order == null)
            throw new Exception("订单不存在!");
        orders.Remove(order);
    }

    public void UpdateOrder(Order updatedOrder)
    {
        Order order = orders.FirstOrDefault(o => o.OrderId == updatedOrder.OrderId);
        if (order == null)
            throw new Exception("订单不存在!");
        orders.Remove(order);
        orders.Add(updatedOrder);
    }

    public List<Order> ByName(String name)
    {
        var ans = from o in orders where o.Customer == name select o;
        return ans.ToList<Order>();
    }
    public List<Order> ByOrderid(int id)
    {
        var ans = from o in orders where o.OrderId == id select o;
        return ans.ToList<Order>();
    }
    public List<Order> ByOrdername(String name)
    {
        var ans = from o in orders where o.OrderDetailsList.Any(d => d.ProductName == name) select o;
        return ans.ToList<Order>();
    }
    public List<Order> ByMoney(double money)
    {
        var ans = from o in orders where o.TotalAmount==money select o;
        return ans.ToList<Order>();
    }
    public void SortOrders(Func<Order, object> keySelector = null)
    {
        if (keySelector == null)
            orders = orders.OrderBy(o => o.OrderId).ToList();
        else
            orders = orders.OrderBy(keySelector).ToList();
    }
    public void Export(string filePath)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(List<Order>));
        using (StreamWriter writer = new StreamWriter(filePath))
        {
            serializer.Serialize(writer, orders);
        }
    }

    public void Import(string filePath)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(List<Order>));
        using (StreamReader reader = new StreamReader(filePath))
        {
            orders = (List<Order>)serializer.Deserialize(reader);
        }
    }
}
[TestFixture]
public class OrderServiceTests
{
    private OrderService orderService;
    private Order testOrder;

    [SetUp]
    public void Setup()
    {
        orderService = new OrderService();
        testOrder = new Order(1, "Test Customer");
        testOrder.AddOrderDetail(new OrderDetails(1, "Test Product", 1, 100.0));
        orderService.AddOrder(testOrder);
    }

    [Test]
    public void TestAddOrder()
    {
        Assert.Throws<Exception>(() => orderService.AddOrder(testOrder), "订单已存在!");
    }

    [Test]
    public void TestRemoveOrder()
    {
        orderService.RemoveOrder(1);
        Assert.AreEqual(0, orderService.ByOrderid(1).Count);
    }

    [Test]
    public void TestByName()
    {
        var orders = orderService.ByName("Test Customer");
        Assert.AreEqual(1, orders.Count);
        Assert.AreEqual("Test Customer", orders[0].Customer);
    }

    [Test]
    public void TestByOrderid()
    {
        var orders = orderService.ByOrderid(1);
        Assert.AreEqual(1, orders.Count);
        Assert.AreEqual(1, orders[0].OrderId);
    }

    [Test]
    public void TestByOrdername()
    {
        var orders = orderService.ByOrdername("Test Product");
        Assert.AreEqual(1, orders.Count);
    }

    [Test]
    public void TestByMoney()
    {
        var orders = orderService.ByMoney(100.0);
        Assert.AreEqual(1, orders.Count);
    }

    [Test]
    public void TestSortOrders()
    {
        orderService.SortOrders(o => o.Customer);
        Assert.AreEqual("Test Customer", orderService.ByOrderid(1)[0].Customer);
    }

    [Test]
    public void TestExportImport()
    {
        string filePath = "orders.xml";
        orderService.Export(filePath);
        orderService = new OrderService();
        orderService.Import(filePath);
        var orders = orderService.ByOrderid(1);
        Assert.AreEqual(1, orders.Count);
    }
}
